package org.javarosa.activity.mesh4j.extensions;

import java.util.Vector;

import org.javarosa.core.Context;
import org.javarosa.core.api.Constants;
import org.javarosa.core.api.IActivity;
import org.javarosa.core.api.ICommand;
import org.javarosa.core.api.IShell;
import org.javarosa.core.services.mesh4j.extensions.SyncEngineService;
import org.javarosa.core.services.transport.TransportMessage;
import org.javarosa.view.ConsoleScreen;
import org.javarosa.view.IConsoleActionListener;
import org.javarosa.view.IMessageRefreshController;
import org.javarosa.view.MessageWithRefreshScreen;
import org.mesh4j.sync.model.Item;
import org.mesh4j.sync.validations.MeshException;

public class SyncActivity implements IActivity, IConsoleActionListener, IMessageRefreshController {

	// MODEL VARIABLES
	private Context context;
	private IShell shell;
	private ConsoleScreen consoleScreen;
	private MessageWithRefreshScreen submitStatusScreen;
	private String formName;
	private String smsNumber;
	private boolean useHttpSync = true;
	private boolean viewConsoleOnly = false;
	private boolean forceRetries = false;
	private boolean cancelSync = false;
	protected int sendStatus;
	
	// BUSINESS METHODS
	
	public SyncActivity(IShell mainShell) {
		this.shell = mainShell;
	}

	public void contextChanged(Context globalContext) {
		context.mergeInContext(globalContext);
	}

	public void destroy() {
		// Nothing for this Module
	}

	public void halt() {
		// Nothing for this Module
	}

	public void resume(Context globalContext) {
		this.execute();		
	}

	public void start(Context context) {
		this.context = context;
		this.execute();
	}

	private void execute() {
		if(this.useHttpSync){
			this.submitStatusScreen = new MessageWithRefreshScreen("Http sync", this);		
			this.shell.setDisplay(this, this.submitStatusScreen);
			new WorkerThread().start();
		} else {
			this.consoleScreen = new ConsoleScreen(this);
			this.shell.setDisplay(this, consoleScreen);
			if(!this.viewConsoleOnly){
				new WorkerThread().start();
			}
		}
	}

	private class WorkerThread implements Runnable {		
		public void start(){
			new Thread(this).start();
		}		
		public void run() {
			executeAction();
		}
	}
	
	private void executeAction() {
		try{
			if(this.useHttpSync){
				this.sendStatus = TransportMessage.STATUS_NEW;
				Vector<Item> conflicts = SyncEngineService.synchronizeItemsSynchronousHttpMethod(this.formName);
							
				if(!conflicts.isEmpty()){
					this.sendStatus = TransportMessage.STATUS_FAILED;
				} else {
					this.sendStatus = TransportMessage.STATUS_DELIVERED;
				}
			} else {
				if(this.cancelSync){
					SyncEngineService.cancelSync(this.formName, this.smsNumber);
				} else if(this.forceRetries){
					SyncEngineService.forceSyncRetries();
				} else {
					SyncEngineService.synchronizeItemsAsynchronousSmsMethod(this.formName, this.smsNumber);
				}
			}
		} catch (Throwable e) {
			e.printStackTrace();
			this.sendStatus = TransportMessage.STATUS_FAILED;
		}
	}
	
	public void setFormName(String formName) {
		this.formName = formName;
	}
	
	public void setSmsNumber(String smsNumber) {
		this.smsNumber = smsNumber;
	}

	public void setCancelSmsSync(){
		this.viewConsoleOnly = false;
		this.useHttpSync = false;
		this.cancelSync = true;
		this.forceRetries = false;
	}
	
	public void setUseSmsSync(){
		this.viewConsoleOnly = false;
		this.useHttpSync = false;
		this.cancelSync = false;
		this.forceRetries = false;
	}
	
	public void setUseHttpSync(){
		this.viewConsoleOnly = false;		
		this.useHttpSync = true;
		this.cancelSync = false;
		this.forceRetries = false;
	}
	
	public void setViewConsoleOnly(){
		this.viewConsoleOnly = true;
		this.useHttpSync = false;
		this.cancelSync = false;
		this.forceRetries = false;
	}
	
	public void setForceRetries(){
		this.viewConsoleOnly = false;
		this.useHttpSync = false;
		this.cancelSync = false;
		this.forceRetries = true;
	}

	public void exit() {
		this.shell.returnFromActivity(this, Constants.ACTIVITY_COMPLETE, null);		
	}

	public String getMessage() {
		String message = "";		
		switch (this.sendStatus) {
			case TransportMessage.STATUS_NEW:       message = "Sending..."; break;
			case TransportMessage.STATUS_DELIVERED: message = "Form has been submitted successfully!"; break;
			case TransportMessage.STATUS_RECEIVED:  message = "Form has been received successfully!"; break;
			case TransportMessage.STATUS_FAILED:    message = "Submission failed! Please try to submit the form again later in 'View Saved'."; break;
			default:                                message = "Unknown sending error; form not sent!"; break;
		}
		return message;

	}

	public boolean shouldBeContinue() {
		return this.sendStatus == TransportMessage.STATUS_NEW;
	}

	public Context getActivityContext() {
		return this.context;
	}

	public void setShell(IShell shell) {
		this.shell = shell;
	}
	/* (non-Javadoc)
	 * @see org.javarosa.core.api.IActivity#annotateCommand(org.javarosa.core.api.ICommand)
	 */
	public void annotateCommand(ICommand command) {
		throw new RuntimeException("The Activity Class " + this.getClass().getName() + " Does Not Yet Implement the annotateCommand Interface Method. Please Implement It.");
	}
}